<?php
/**
 * Created by PhpStorm.
 * User: inhere
 * Date: 2016/3/25
 * Time: 14:49
 */

namespace app\controllers;

use app\extensions\MDerPager;
use app\handlers\HandlerFactory;
use slimExt\base\Request;
use slimExt\base\Response;
use Slim;
use app\helpers\exceptions\FileSystemException;
use app\requests\PageRequest;
use app\parsers\DefaultParser;
use app\extensions\DataEnum;
use app\extensions\MderPage;
use slimExt\DataCollector;
use Symfony\Component\Yaml\Dumper;

/**
 * Class Page
 * @package app\controllers
 */
class Page extends Base
{
    protected $tplPathPrefix = 'mder';

    /**
     * render and display markdown file
     * @api match all, except /_mder
     *
     * @return Response
     * @throws \RuntimeException
     */
    public function viewAction()
    {
        $req = $this->request;
        $page =  $req->getAttribute('page');

        /** @var \app\extensions\ProjectManager $pm */
 //         $pm = Slim::$app->pm;
 //         $pm->loadConfig();
 //         $pager = new MDerPager($page);
 // de($pm);
        /** @var \app\handlers\AbstractHandler $handler */
        $handler = HandlerFactory::getHandler($page);
        $pager = $handler->getPager();

        // page don't exists
        if ( !$pager->findPageFile() ) {

            if ($req->isXhr()) {
                return $this->response->withJson('Page not found!');
            }

            return $this->renderTwig('noPage', [
                'createPage' => '/_mder/page/add?page=' . $page,
                'page'       => $pager->getPageUrl(),
                'attrs'      => [
                    'route'      => slim_config('urls.route',''),
                    'pageTitle'  => 'Page not found!',
                    'keywords'   => '',
                    'description' => 'Page not found!',
                ],
                'params'     => $req->getParams()
            ]);
        }

        $handler->read();
        $oldHash = $handler->getViewVar('oldHash', null);
        $content = $handler->getViewVar('content', '');

        // If not enabled detection change and have already rendered static files, loading already rendered output file content.
        if ( $oldHash === false ) {
            return $this->response->getBody()->write($content);
        }

        $pagePath = $pager->getPageUrl();
        $handler
            ->addViewVar('projectName', $pager->getItem()->getOption('name', $pager->getItemName()))
            ->addViewVar('pagePath', $pagePath)
            ->addViewVar('filename', basename($pagePath));

        $view = $pager->getItem()->getOption('contentTpl') ?: 'page';

        $rendered = $this->renderTwig($view, $handler->getViewVars(), static::RETURN_RENDERED);

        $handler->cacheToFile($oldHash, $rendered);

        return $this->response->getBody()->write($rendered);
    }

    /**
     * @return string
     */
    public function addAction()
    {
        if ( $this->request->isPost() ) {
            return $this->doAdd();
        }

        list(, $tplVar) = $this->baseHandle($this->request, false);

        $tplVar['page']['setting'] = '';

        return $this->renderTwig('add', $tplVar);
    }

    /**
     * @return string
     */
    protected function doAdd()
    {
        $page   =  $this->request->getTrimmed('page');

        /** @var \app\handlers\AbstractHandler $handler */
        $handler = HandlerFactory::getHandler($page, true);
        $pager = $handler->getPager();
//        $pagePath = $pager->getPageUrl();

        $success = $handler->write($this->request);

        $type    = 'danger';
        $pageUrl = '/_mder/page/add';

        if ( $success ) {
            $pageUrl = $pager->getPageUrl(true);
            $type   = 'success';
            $msg   = "create page [$page] successful!!";
        } else {
            $msg   = $handler->getError();
        }
//de($handler);
        return $this->response->withRedirect($pageUrl)->withMessage([
            'type' => $type,
            'msg'  => $msg,
        ]);
    }

    /**
     * @method GET
     * @api /_mder/page/edit
     * @arguments {
     *  page        string    the edit's page file path
     *  useSource   bool      edit source file?
     * }
     *
     * @return string
     * @throws \HttpRequestException
     */
    public function editAction()
    {
        if ( $this->request->isPost() ) {
            return $this->doEdit();
        }

        list($file, $tplVar) = $this->baseHandle($this->request);

        // read content
        if ( ( $content = file_get_contents($file) ) === false ) {
            throw new \RuntimeException("An error occurred while reading the file. File: {$file}");
        }

        $parser = DefaultParser::make(new MderPage($tplVar['page']['path']));
        list($setting, $content) = $parser->splitDataContent($content);

        $tplVar['page']['setting'] = $setting;
        $tplVar['page']['content'] = $content;

        return $this->renderTwig('edit', $tplVar);
    }

    /**
     * @method POST
     * @api /_mder/page/edit
     * @arguments {
     * }
     *
     * @return string
     */
    protected function doEdit()
    {
        $page   =  $this->request->getTrimmed('page');

        /** @var \app\handlers\AbstractHandler $handler */
        $handler = HandlerFactory::getHandler($page, false);
        $pager = $handler->getPager();
//        $pagePath = $pager->getPageUrl();

        $success = $handler->write($this->request);
        $msg   = "update page [$page] successful!!";

//        $url = Slim::$app->router->pathFor('mder-page',['action'=> 'edit']);

        return $this->response->withRedirect($page)->withMessage([
            'type' => $success ? 'success' : 'danger',
            'msg'  => $success ? $msg : $handler->getError(),
        ]);
    }

    /**
     * @return string
     * @throws \InvalidArgumentException
     */
    public function delAction()
    {
        $type  = 'warning';
        $title = 'Warning';

        if ( !$page = $this->request->getParam('page','') ) {
            $msg = 'Required parameter missing!';
        } else {
            $type  = 'success';
            $title = 'Successful';
            $msg   = 'delete ['.$page.'] successful!!';
        }

        // when is xhr
        if ( $this->request->isXhr() ) {
            return $this->response->withJson( __LINE__, $msg );
        }

        alert_messages(['type'=>$type, 'title'=>$title, 'msg' => $msg]);

        return redirect_to( Slim::$app->router->pathFor('mder-page',['action'=> 'index']) );
    }

    protected function baseHandle(Request $req, $checkFile=true)
    {
        $config = Slim::get('config');
        $config->set('params.navbarFixedTop',false)->set('params.navbarClass', 'navbar navbar-default');

        $page   = trim($req->getParam('page',''), '/_ ');
        if ($checkFile && !$page ) {
            throw new \InvalidArgumentException('Required parameter missing!');
        }

        // fix first char is not '/'
        if ($page) {
            $page   = '/' . trim($page, '/_ ');
        }

        $pager = new MderPage($page);

        if ($checkFile &&  !$pager->findPageFile() ) {
            throw new \InvalidArgumentException('Page don\'t existing.');
        }

        $file = $pager->dataFile;

        $tplVar = [
            'page'   => [
                'path'    => $page,
                'basePath' => $config->get('sources.path'),
                'fullPath' => $file,
                'setting' => '',
                'content' => '',
            ],
        ];

        $parser = DefaultParser::make();
        $tplVar['attrs'] = $parser->getAttrs();
        $tplVar['allowStatus'] = DataEnum::getStatusList();
        $tplVar['allowSettings'] = $parser->getAllowSetting();

        // $this->tplGlobalVarList['csrf_field'] = $this->csrfField($req);
        $this->tplGlobalVarList['csrf_field'] = '';

        return [$file, $tplVar];
    }

}
